<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>火币交易可视化</title>
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcss.com/socket.io/1.5.1/socket.io.min.js"></script>
    <!--<script type="text/javascript" src={{url_for('static', filename='jquery-1.8.3.min.js')}}></script>-->
    <script type="text/javascript" src={{url_for('static', filename='echarts.min.js')}}></script>
    <style>
        body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.428571429;
  color: #333333;
  background-color: #ffffff;
}
<!--.row {-->
  <!--box-sizing: content-box;-->
<!--}-->

    .row::before{
        content: '';
       border-top:25px solid transparent;
        border-bottom:20px solid transparent;

        .row::after{
        content: '';
       border-top:25px solid transparent;
        border-bottom:20px solid transparent;

     #trade
{
height:400px; //高度要固定
overflow:scroll; //超过部分使用滚动条
}


    </style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container-fluid">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">火币交易可视化</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
            <li><a href="#account">账户</a></li>
            <li><a href="#trade">成交</a></li>
            <li><a href="#">持仓</a></li>
            <li><a href="#">帮助</a></li>
          </ul>
          <form class="navbar-form navbar-right">
            <input type="text" class="form-control" placeholder="Search...">
          </form>
        </div>
      </div>
    </nav>

<div class="container-fluid" style="margin-top:20px;">
    <div class="row">
        <div class="col-sm-12 col-sm-offset-* col-md-12 col-md-offset-* main">
        <h1 class="page-header">Trading</h1>
            <div class="btn-toolbar" role="toolbar" aria-label="Toolbar">
                <div class="btn-group" role="group" aria-label="ws_connect">
                    <button type="button" class="btn btn-primary btn-sm" id="connect_websocket">连接</button>
                    <button type="button" class="btn btn-dark btn-sm" id="close_websocket">断开</button>
                </div>
                <div class="btn-group" role="group" aria-label="draw_kline">
                    <button type="button" class="btn btn-success btn-sm" id="send_message">开始画图</button>
                    <button type="button" class="btn btn-danger btn-sm" id="close_ht">暂停画图</button>
                </div>
                <div class="btn-group">

                <form class="form-inline">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="bar counts" aria-describedby="btnGroupAddon" id="message" aria-label="Input group" value="200">
                    <label for="message">@</label>
                      <input type="text" class="form-control" placeholder="code" aria-describedby="btnGroupAddon" id="code" aria-label="Input group" value="dcreth" readonly>
                </div>

                    </form>
            </div>
</div>

        <div class="row placeholders">
            <div class="jumbotron" id="main" style="width: auto;height: 500px;" align="center"></div>
        </div>

            <div class="col-sm-7 col-md-6" id="app">

    <div class="dropdown"> <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown">
    代码:
    <span class="caret"></span> </button>
        <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1" >
            <li role="presentation" v-for="c in codes">
                <a role="menuitem" tabindex="-1" href="#c">{[c]}</a>
            </li>
         </ul>
    </div>

        <!--<h2 class="sub-header">回测数据</h2>-->

        <div class="table-responsive">
            <table class="table table-striped" id="accounts">
            <caption>账户信息</caption>
           <thead>
              <tr>
                  <!--<th>时间</th>-->
                  <th>账户ID</th>
                  <th>币种</th>
                  <th>账户类型</th>
                  <th>账户余额</th>
              </tr>
           </thead>
           <tbody>
                <tr v-for="a in accounts">
                    <td>{[a['account-id']]}</td>
                    <td>{[a.currency]}</td>
                    <td>{[a.type]}</td>
                    <td>{[a.balance]}</td>
                </tr>
           </tbody>
        </table>
            <table class="table table-striped table-hover table-condensed" id="trades">
                <caption>交易信息</caption>
               <thead>
                  <tr>
                      <th>流水号</th>
                      <th>订单ID</th>
                      <th>交易对</th>
                      <th>帐号ID</th>
                      <th>订单数量</th>
                      <th>订单价格</th>
                      <th>创建时间</th>
                      <th>类型</th>
                      <th>来源</th>
                      <th>状态</th>
                      <th>Role</th>
                      <th>成交价格</th>
                      <th>成交数量</th>
                      <th>未成交数量</th>
                      <th>成交金额</th>
                      <th>手续费</th>
                  </tr>
               </thead>
               <tbody>
                    <tr v-for="t in trades">
                        <td>{[t['seq-id']]}</td>
                        <td>{[t['order-id']]}</td>
                        <td>{[t['symbol']]}</td>
                        <td>{[t['account-id']]}</td>
                        <td>{[t['order-amount']]}</td>
                        <td>{[t['order-price']]}</td>
                        <td>{[t['created-at']]}</td>
                        <td>{[t['order-type']]}</td>
                        <td>{[t['order-source']]}</td>
                        <td>{[t['order-state']]}</td>
                        <td>{[t['role']]}</td>
                        <td>{[t['price']]}</td>
                        <td>{[t['filled-amount']]}</td>
                        <td>{[t['unfilled-amount']]}</td>
                        <td>{[t['filled-cash-amount']]}</td>
                        <td>{[t['filled-fees']]}</td>
                    </tr>
               </tbody>
            </table>

        </div>
                </div>
    </div>
        <!--<div class="col-sm-3 col-md-2 sidebar">-->
      <!--<ul class="nav nav-sidebar">-->
        <!--<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>-->
        <!--<li><a href="#">Reports</a></li>-->
        <!--<li><a href="#">Analytics</a></li>-->
        <!--<li><a href="#">Export</a></li>-->
      <!--</ul>-->
      <!--<ul class="nav nav-sidebar">-->
        <!--<li><a href="">Nav item</a></li>-->
        <!--<li><a href="">Nav item again</a></li>-->
        <!--<li><a href="">One more nav</a></li>-->
        <!--<li><a href="">Another nav item</a></li>-->
        <!--<li><a href="">More navigation</a></li>-->
      <!--</ul>-->
      <!--<ul class="nav nav-sidebar">-->
        <!--<li><a href="">Nav item again</a></li>-->
        <!--<li><a href="">One more nav</a></li>-->
        <!--<li><a href="">Another nav item</a></li>-->
      <!--</ul>-->
    <!--</div>-->
    </div>
</div>

<footer class="footer navbar-fixed-bottom">
      <div class="container">
        <p class="text-muted" align="center" style="margin-top: 20px;color:#878B91;">huobitrade可视化@copyright 2018</p>
        </div>
    </footer>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var categoryData = new Object();
var bar = new Object();
var trade = new Object();
var extra = new Object();
var is_huatu = true;
var size = $('#message').val()-0;
var code = $('#code').val();
var max_bar = 1000;
var is_first = true;
var draw_counts = 0;

option = {
    title : {
        <!--text: '回测',-->
        <!--subtext: 'K线'-->
    },
    grid: {
        show:'true',
        borderWidth:'0',
        x: '0',
        y: '0',
        x2: '0',
        y2: '0',
        width: '100%',
        height: '100%'
    },
    tooltip : {
        trigger: 'axis'
    },
    legend: {
        data:['KLine', 'MA5',  'MA10', 'MA30', 'MA60']
    },
    toolbox: {
        show : true,
        feature : {
            mark : {show: true},
            dataView : {show: true, readOnly: false},
            restore : {show: true},
            saveAsImage : {show: true}
        }
    },
    dataZoom : {
        show : true,
        realtime: true,
    },
    xAxis : [
        {
            type : 'category',
            boundaryGap : true,
            data : [

            ]
        }
    ],
    yAxis : [
        {
            type : 'value',
            scale: true,
            splitNumber: 5,
            boundaryGap: [0.05, 0.05]
        }
    ],
    series : [
        {
            name: 'KLine',
            type: 'k',
            dimensions: ['date', 'open', 'close', 'highest', 'lowest'],
            encode: {
                x: 'date',
                y: ['open', 'close', 'highest', 'lowest']
                },
            data: [ // 开盘，收盘，最低，最高
            ],
            zlevel: 0,
            markPoint: {
                label: {
                    normal: {
                        formatter: function (param) {
                            return param != null ? Math.round(param.value) : '';
                        },
                    position: 'right',
                    fontSize: 8
                    }
                },
                data: [

                ],
                tooltip: {
                    formatter: function (param) {
                        return param.name + '<br>' + (param.data.coord || '');
                    }
                }
            }
        },
        {
            name: 'MA5',
            type: 'line',
            data: [],
            smooth: true,
            zlevel: 1,
            lineStyle: {
                normal: {opacity: 0.5}
                }
        },
                {
            name: 'MA10',
            type: 'line',
            data: [],
            smooth: true,
            zlevel: 1,
            lineStyle: {
                normal: {opacity: 0.5}
                }
        },
                {
            name: 'MA30',
            type: 'line',
            data: [],
            smooth: true,
            zlevel: 1,
            lineStyle: {
                normal: {opacity: 0.5}
                }
        },
                {
            name: 'MA60',
            type: 'line',
            data: [],
            smooth: true,
            zlevel: 1,
            lineStyle: {
                normal: {opacity: 0.5}
                }
        },
    ]
}

var vm = new Vue({
el: '#app',
delimiters: ['{[', ']}'],
data:{
bar: [],
accounts: {},
position: {},
trades: [],
codes: [],
Eoption: option},
watch:{
           bar:{//深度监听，可监听到对象、数组的变化
            handler(val){
                this.Eoption.series[0].data = val.map(function(d){return d.slice(1, 5)});
                this.Eoption.xAxis[0].data = val.map(function(d){return d[0]});
                myChart.setOption(this.Eoption);
            },
            deep:true
            }
}
<!--computed: {-->
    <!--codes : function(){-->
        <!--return Object.keys(this.bar);-->
    <!--}}-->
    }
    )

myChart.showLoading();

function addTrade(trade_data){
    data = [trade_data.trading_datetime, trade_data.last_price, trade_data.side];
    vm.trade.unshift(trade_data);

    var trade_point = {
                    name: 'trade',
                    symbol: 'triangle',
                    symbolSize: 10,
                    coord: [data[0], data[1]],
                    value: data[1],
                    itemStyle: {
                        normal: {color: 'rgb(41,60,85)'}
                    }
                    };

    if(data[2]=='SELL'){
        trade_point.itemStyle.normal.color = 'rgb(0,255,0)';
        trade_point.symbolRotate = -180;
    }else{
        trade_point.itemStyle.normal.color = 'rgb(255,0,0)';
        trade_point.symbolRotate = 0;
    }

    if(trade_data.order_book_id in trade){
        trade[trade_data.order_book_id].push(trade_point);
    }else{
        trade[trade_data.order_book_id] = [];
        trade[trade_data.order_book_id].push(trade_point);
    }

    option.series[0].markPoint.data = trade[code];

    <!--if(is_huatu){-->
        <!--myChart.setOption(option);-->
    <!--}-->
}

function addExtra(data){

    <!--_data = [data.datetime, data.topic_vals.values()];-->
    if(data.code in extra){
        <!--extra[data.code].push(_data);-->
    }else{
        extra[data.code] = {};
        <!--extra[data.code].push(_data);-->
    }


    for(t in data.topic_vals){
        if(t in extra[data.code]){
            extra[data.code][t].push(data.topic_vals[t]);
        }else{
            extra[data.code][t] = [];
            extra[data.code][t].push(data.topic_vals[t]);
        }
    }
    _current_extra = extra[code]
    for (topic in _current_extra){
        if (topic=='MA5'){
            option.series[1].data = _current_extra[topic].slice(-max_bar)
        }else if (topic=='MA10'){
            option.series[2].data = _current_extra[topic].slice(-max_bar)
        }else if (topic=='MA30'){
            option.series[3].data = _current_extra[topic].slice(-max_bar)
        }else if (topic=='MA60'){
            option.series[4].data = _current_extra[topic].slice(-max_bar)
        }
    }

}

function updateAccount(data){
        vm.account = data;
}

function updatePosition(data){
    vm.position[data['order_book_id']] = data;
}

myChart.hideLoading();

$(document).ready(function() {
    namespace = '/ws';
    console.log(location.protocol + '//' + document.domain + ':' + location.port + namespace);
    var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
        socket.on('klines', function(klines) {
            <!--option.series[0].data = [];-->
            klines.reverse();
            temp_bar = [];
            for (let k of klines){
                temp_bar.push([k.id, k.open, k.close, k.high, k.low]);
            }
            vm.bar = temp_bar;
    });
        socket.on('kline_tick', function(k) {
            if (vm.bar[vm.bar.length - 1][0] == k['id']){
                vm.bar.splice(-1, 1, [k.id, k.open, k.close, k.high, k.low]);
            }else{
                vm.bar.push([k.id, k.open, k.close, k.high, k.low]);
            }
    });
        socket.on('accounts', function(acc) {
            vm.accounts = acc.list;
            console.log(acc);
    });
        socket.on('orders', function(order) {
            up_to_date = false;
            for (var i in vm.trades){
                if(order['order-id'] == vm.trades[i]['order-id']){
                    vm.trades[i] = order;
                    up_to_date = true;
                    break;
                }
            }
            if(!up_to_date){vm.trades.push(order)};
            console.log(order)
    });
        socket.on('connect', function(res) {
        socket.emit('get_klines', { symbol: code, period: '1min' });
        socket.emit('sub_kline', { symbol: code, period: '1min' });
        console.log(res);
    });
    <!--setTimeout(function(){-->
        <!--socket.emit('sub_accounts');-->
    <!--}, 5000)-->
    $.get('/data/get_symbols',{},function(data){
        symbols = JSON.parse(data);
        vm.codes = [];
        for (var i in symbols){
            vm.codes.push(symbols[i].symbol);
            }
        console.log(symbols);
    });
    $("[href='#c']").on('click', function(){
            console.log('tesing');
            <!--console.log($(this).text());-->
            <!--old_code =  $('#code').val();-->
            <!--new_code = this.text;-->
            <!--$('#code').val(c);-->
            <!--socket.emit('unsub_kline', { symbol: old_code, period: '1min' });-->
            <!--socket.emit('get_klines', { symbol: new_code, period: '1min' });-->
            <!--socket.emit('sub_kline', { symbol: new_code, period: '1min' });-->
            <!--option.legend.data = [code, 'MA5',  'MA10', 'MA30', 'MA60'];-->
    });

});
</script>
</body>
</html>